From 4e9b2c5c5341be17a88a2d9f3c69d1a34093c4b9 Mon Sep 17 00:00:00 2001 From: "Mark A. Hershberger" Date: Wed, 6 Apr 2011 19:50:54 +0000 Subject: [PATCH] =?utf8?q?Apply=20modification=20of=20mdale's=20patch=20fr?= =?utf8?q?om=20Bug=20#28420:=20=E2=80=9CRe-factor=20upload=20tests=20to=20?= =?utf8?q?support=20extensions=20extending=20upload=20test=20case=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- tests/phpunit/includes/api/ApiTestCase.php | 64 +++++ .../includes/api/ApiTestCaseUpload.php | 128 +++++++++ tests/phpunit/includes/api/ApiTestUser.php | 59 +++++ tests/phpunit/includes/api/ApiUploadTest.php | 242 +----------------- 4 files changed, 253 insertions(+), 240 deletions(-) create mode 100644 tests/phpunit/includes/api/ApiTestCase.php create mode 100644 tests/phpunit/includes/api/ApiTestCaseUpload.php create mode 100644 tests/phpunit/includes/api/ApiTestUser.php diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php new file mode 100644 index 0000000000..4907c79292 --- /dev/null +++ b/tests/phpunit/includes/api/ApiTestCase.php @@ -0,0 +1,64 @@ + new ApiTestUser( + 'Apitestsysop', + 'Api Test Sysop', + 'api_test_sysop@sample.com', + array( 'sysop' ) + ), + 'uploader' => new ApiTestUser( + 'Apitestuser', + 'Api Test User', + 'api_test_user@sample.com', + array() + ) + ); + + $wgUser = self::$users['sysop']->user; + + } + + protected function doApiRequest( $params, $session = null, $appendModule = false ) { + if ( is_null( $session ) ) { + $session = array(); + } + + $request = new FauxRequest( $params, true, $session ); + $module = new ApiMain( $request, true ); + $module->execute(); + + return array( $module->getResultData(), $request, $request->getSessionArray() ); + } + + /** + * Add an edit token to the API request + * This is cheating a bit -- we grab a token in the correct format and then add it to the pseudo-session and to the + * request, without actually requesting a "real" edit token + * @param $params: key-value API params + * @param $session: session array + */ + protected function doApiRequestWithToken( $params, $session ) { + if ( $session['wsToken'] ) { + // add edit token to fake session + $session['wsEditToken'] = $session['wsToken']; + // add token to request parameters + $params['token'] = md5( $session['wsToken'] ) . User::EDIT_TOKEN_SUFFIX; + return $this->doApiRequest( $params, $session ); + } else { + throw new Exception( "request data not in right format" ); + } + } + +} diff --git a/tests/phpunit/includes/api/ApiTestCaseUpload.php b/tests/phpunit/includes/api/ApiTestCaseUpload.php new file mode 100644 index 0000000000..a7fc9bd3d3 --- /dev/null +++ b/tests/phpunit/includes/api/ApiTestCaseUpload.php @@ -0,0 +1,128 @@ +clearFakeUploads(); + } + + /** + * Fixture -- run after every test + * Clean up temporary files etc. + */ + function tearDown() { + } + + + /** + * Helper function -- remove files and associated articles by Title + * @param $title Title: title to be removed + */ + public function deleteFileByTitle( $title ) { + if ( $title->exists() ) { + $file = wfFindFile( $title, array( 'ignoreRedirect' => true ) ); + $noOldArchive = ""; // yes this really needs to be set this way + $comment = "removing for test"; + $restrictDeletedVersions = false; + $status = FileDeleteForm::doDelete( $title, $file, $noOldArchive, $comment, $restrictDeletedVersions ); + if ( !$status->isGood() ) { + return false; + } + $article = new Article( $title ); + $article->doDeleteArticle( "removing for test" ); + + // see if it now doesn't exist; reload + $title = Title::newFromText( $fileName, NS_FILE ); + } + return ! ( $title && $title instanceof Title && $title->exists() ); + } + + /** + * Helper function -- remove files and associated articles with a particular filename + * @param $fileName String: filename to be removed + */ + public function deleteFileByFileName( $fileName ) { + return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) ); + } + + + /** + * Helper function -- given a file on the filesystem, find matching content in the db (and associated articles) and remove them. + * @param $filePath String: path to file on the filesystem + */ + public function deleteFileByContent( $filePath ) { + $hash = File::sha1Base36( $filePath ); + $dupes = RepoGroup::singleton()->findBySha1( $hash ); + $success = true; + foreach ( $dupes as $dupe ) { + $success &= $this->deleteFileByTitle( $dupe->getTitle() ); + } + return $success; + } + + /** + * Fake an upload by dumping the file into temp space, and adding info to $_FILES. + * (This is what PHP would normally do). + * @param $fieldName String: name this would have in the upload form + * @param $fileName String: name to title this + * @param $type String: mime type + * @param $filePath String: path where to find file contents + */ + function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) { + $tmpName = tempnam( wfTempDir(), "" ); + if ( !file_exists( $filePath ) ) { + throw new Exception( "$filePath doesn't exist!" ); + }; + + if ( !copy( $filePath, $tmpName ) ) { + throw new Exception( "couldn't copy $filePath to $tmpName" ); + } + + clearstatcache(); + $size = filesize( $tmpName ); + if ( $size === false ) { + throw new Exception( "couldn't stat $tmpName" ); + } + + $_FILES[ $fieldName ] = array( + 'name' => $fileName, + 'type' => $type, + 'tmp_name' => $tmpName, + 'size' => $size, + 'error' => null + ); + + return true; + + } + + /** + * Remove traces of previous fake uploads + */ + function clearFakeUploads() { + $_FILES = array(); + } + + + + +} diff --git a/tests/phpunit/includes/api/ApiTestUser.php b/tests/phpunit/includes/api/ApiTestUser.php new file mode 100644 index 0000000000..df60682f54 --- /dev/null +++ b/tests/phpunit/includes/api/ApiTestUser.php @@ -0,0 +1,59 @@ +username = $username; + $this->realname = $realname; + $this->email = $email; + $this->groups = $groups; + + // don't allow user to hardcode or select passwords -- people sometimes run tests + // on live wikis. Sometimes we create sysop users in these tests. A sysop user with + // a known password would be a Bad Thing. + $this->password = User::randomPassword(); + + $this->user = User::newFromName( $this->username ); + $this->user->load(); + + // In an ideal world we'd have a new wiki (or mock data store) for every single test. + // But for now, we just need to create or update the user with the desired properties. + // we particularly need the new password, since we just generated it randomly. + // In core MediaWiki, there is no functionality to delete users, so this is the best we can do. + if ( !$this->user->getID() ) { + // create the user + $this->user = User::createNew( + $this->username, array( + "email" => $this->email, + "real_name" => $this->realname + ) + ); + if ( !$this->user ) { + throw new Exception( "error creating user" ); + } + } + + // update the user to use the new random password and other details + $this->user->setPassword( $this->password ); + $this->user->setEmail( $this->email ); + $this->user->setRealName( $this->realname ); + // remove all groups, replace with any groups specified + foreach ( $this->user->getGroups() as $group ) { + $this->user->removeGroup( $group ); + } + if ( count( $this->groups ) ) { + foreach ( $this->groups as $group ) { + $this->user->addGroup( $group ); + } + } + $this->user->saveSettings(); + + } + +} diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php index e468f66f9c..a51e29df39 100644 --- a/tests/phpunit/includes/api/ApiUploadTest.php +++ b/tests/phpunit/includes/api/ApiUploadTest.php @@ -14,129 +14,9 @@ // This framework works better IMO and has less strangeness (such as test cases inheriting from "ApiSetup"...) // (and in the case of the other Upload tests, this flat out just actually works... ) -// TODO: refactor into several files // TODO: port the other Upload tests, and other API tests to this framework -/* Wraps the user object, so we can also retain full access to properties like password if we log in via the API */ -class ApiTestUser { - public $username; - public $password; - public $email; - public $groups; - public $user; - - function __construct( $username, $realname = 'Real Name', $email = 'sample@sample.com', $groups = array() ) { - $this->username = $username; - $this->realname = $realname; - $this->email = $email; - $this->groups = $groups; - - // don't allow user to hardcode or select passwords -- people sometimes run tests - // on live wikis. Sometimes we create sysop users in these tests. A sysop user with - // a known password would be a Bad Thing. - $this->password = User::randomPassword(); - - $this->user = User::newFromName( $this->username ); - $this->user->load(); - - // In an ideal world we'd have a new wiki (or mock data store) for every single test. - // But for now, we just need to create or update the user with the desired properties. - // we particularly need the new password, since we just generated it randomly. - // In core MediaWiki, there is no functionality to delete users, so this is the best we can do. - if ( !$this->user->getID() ) { - // create the user - $this->user = User::createNew( - $this->username, array( - "email" => $this->email, - "real_name" => $this->realname - ) - ); - if ( !$this->user ) { - throw new Exception( "error creating user" ); - } - } - - // update the user to use the new random password and other details - $this->user->setPassword( $this->password ); - $this->user->setEmail( $this->email ); - $this->user->setRealName( $this->realname ); - // remove all groups, replace with any groups specified - foreach ( $this->user->getGroups() as $group ) { - $this->user->removeGroup( $group ); - } - if ( count( $this->groups ) ) { - foreach ( $this->groups as $group ) { - $this->user->addGroup( $group ); - } - } - $this->user->saveSettings(); - - } - -} - -abstract class ApiTestCase extends MediaWikiTestCase { - public static $users; - - function setUp() { - global $wgContLang, $wgAuth, $wgMemc, $wgRequest, $wgUser; - - $wgMemc = new EmptyBagOStuff(); - $wgContLang = Language::factory( 'en' ); - $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' ); - $wgRequest = new FauxRequest( array() ); - - self::$users = array( - 'sysop' => new ApiTestUser( - 'Apitestsysop', - 'Api Test Sysop', - 'api_test_sysop@sample.com', - array( 'sysop' ) - ), - 'uploader' => new ApiTestUser( - 'Apitestuser', - 'Api Test User', - 'api_test_user@sample.com', - array() - ) - ); - - $wgUser = self::$users['sysop']->user; - - } - - protected function doApiRequest( $params, $session = null, $appendModule = false ) { - if ( is_null( $session ) ) { - $session = array(); - } - - $request = new FauxRequest( $params, true, $session ); - $module = new ApiMain( $request, true ); - $module->execute(); - - return array( $module->getResultData(), $request, $request->getSessionArray() ); - } - - /** - * Add an edit token to the API request - * This is cheating a bit -- we grab a token in the correct format and then add it to the pseudo-session and to the - * request, without actually requesting a "real" edit token - * @param $params: key-value API params - * @param $session: session array - */ - protected function doApiRequestWithToken( $params, $session ) { - if ( $session['wsToken'] ) { - // add edit token to fake session - $session['wsEditToken'] = $session['wsToken']; - // add token to request parameters - $params['token'] = md5( $session['wsToken'] ) . User::EDIT_TOKEN_SUFFIX; - return $this->doApiRequest( $params, $session ); - } else { - throw new Exception( "request data not in right format" ); - } - } - -} +require_once( 'ApiTestCaseUpload.php' ); /** * @group Database @@ -144,32 +24,7 @@ abstract class ApiTestCase extends MediaWikiTestCase { * * This is pretty sucky... needs to be prettified. */ -class ApiUploadTest extends ApiTestCase { - /** - * Fixture -- run before every test - */ - public function setUp() { - global $wgEnableUploads, $wgEnableAPI; - parent::setUp(); - - $wgEnableUploads = true; - $wgEnableAPI = true; - wfSetupSession(); - - ini_set( 'log_errors', 1 ); - ini_set( 'error_reporting', 1 ); - ini_set( 'display_errors', 1 ); - - $this->clearFakeUploads(); - } - - /** - * Fixture -- run after every test - * Clean up temporary files etc. - */ - function tearDown() { - } - +class ApiUploadTest extends ApiTestCaseUpload { /** * Testing login @@ -575,98 +430,5 @@ class ApiUploadTest extends ApiTestCase { $this->deleteFileByFilename( $fileName ); unlink( $filePath ); } - - - - /** - * Helper function -- remove files and associated articles by Title - * @param $title Title: title to be removed - */ - public function deleteFileByTitle( $title ) { - if ( $title->exists() ) { - $file = wfFindFile( $title, array( 'ignoreRedirect' => true ) ); - $noOldArchive = ""; // yes this really needs to be set this way - $comment = "removing for test"; - $restrictDeletedVersions = false; - $status = FileDeleteForm::doDelete( $title, $file, $noOldArchive, $comment, $restrictDeletedVersions ); - if ( !$status->isGood() ) { - return false; - } - $article = new Article( $title ); - $article->doDeleteArticle( "removing for test" ); - - // see if it now doesn't exist; reload - $title = Title::newFromText( $fileName, NS_FILE ); - } - return ! ( $title && $title instanceof Title && $title->exists() ); - } - - /** - * Helper function -- remove files and associated articles with a particular filename - * @param $fileName String: filename to be removed - */ - public function deleteFileByFileName( $fileName ) { - return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) ); - } - - - /** - * Helper function -- given a file on the filesystem, find matching content in the db (and associated articles) and remove them. - * @param $filePath String: path to file on the filesystem - */ - public function deleteFileByContent( $filePath ) { - $hash = File::sha1Base36( $filePath ); - $dupes = RepoGroup::singleton()->findBySha1( $hash ); - $success = true; - foreach ( $dupes as $dupe ) { - $success &= $this->deleteFileByTitle( $dupe->getTitle() ); - } - return $success; - } - - /** - * Fake an upload by dumping the file into temp space, and adding info to $_FILES. - * (This is what PHP would normally do). - * @param $fieldName String: name this would have in the upload form - * @param $fileName String: name to title this - * @param $type String: mime type - * @param $filePath String: path where to find file contents - */ - function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) { - $tmpName = tempnam( wfTempDir(), "" ); - if ( !file_exists( $filePath ) ) { - throw new Exception( "$filePath doesn't exist!" ); - }; - - if ( !copy( $filePath, $tmpName ) ) { - throw new Exception( "couldn't copy $filePath to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[ $fieldName ] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - - return true; - - } - - /** - * Remove traces of previous fake uploads - */ - function clearFakeUploads() { - $_FILES = array(); - } - - } -- 2.20.1